/***************************************************************
 * FILENAME:  LAB2.c
 *
 * CREATED: 9/7/2012 8:30:52 AM
 * AUTHOR:    zimmermane@msoe.edu <Evan Zimmerman>
 *            duerk@msoe.edu <Kevin Duer>
 * PROVIDES:  a driver for the whole program
**************************************************************/

#include <avr/io.h>        //to use named components on Atmega 32
#include <avr/interrupt.h> //will include the interrupt vectors
#include <stdint.h>        //for uint8_t
#include <stdbool.h>       //for boolean
#include <stdio.h>
#include "lcd3200.h"
#include "usart3200.h"
#include "helpers.h"


static volatile bool heartBeat;     //used to turn on and off the heartbeat
static volatile bool update_LCD;  //used to update the LCD
static volatile bool welcome;	//used to tell if the Welcome message should be displayed
static volatile bool antenna; //used to display the antenna icon
static volatile bool display_tag_count; //used to display the tag count
static volatile char welcome_count; //counter for the welcome message
static volatile char byte_count; //counter for the RFID value
static volatile char ID[11]; //string of data holding RFID number
static volatile char tag_count; //the count of the number of times a tags have been seen

// set up a file stream which will allow us to use printf to call our lcd_send_data method
// 
FILE lcd_str = FDEV_SETUP_STREAM(lcd_send_data, lcd_send_data, _FDEV_SETUP_RW);

/*
 * display_welcome
 * Purpose: To display the welcome screen on the LCD
 * Parameters: None
 * Returns: None
 */
void display_welcome(void){
	lcd_send_data(0x0C);
	delay_ms(60);
	lcd_gotoxy(0,0);
	printf("CE3200 RFID");
	lcd_gotoxy(1,0);
	printf("WELCOME!");
	lcd_gotoxy(1,15);
	//lcd_send_data(4); // antenna off indicator
	lcd_send_data('_'); //antenna off indicator
}

/*
 * toggle_RFID
 * Purpose: enables or disables the RFID antenna
 * Parameters: None
 * Returns: None
 */
void toggle_RFID(){
	// if PB0 is a 1, the antenna is disabled, so enable it
	if(PINB & (1<<PB0)){
		PORTB = PINB & ~(1<<PB0);
		antenna = true;
	}
	// otherwise the antenna is enabled, so disable it	
	else{
		PORTB = PINB | (1<<PB0);
		antenna = false;
	}
}

/*
 * main
 * Purpose: This will be the method which controls the whole system
 *			it will setup default values and enter into a forever
 *			loop to check set values
 * Parameters: None
 * Returns: None
 */
int main(void){
	
	//setup default values
	heartBeat = false;
	welcome = true;
	welcome_count = 0;
	byte_count = 0;
	tag_count = 0;
	
	stdin = stdout = &lcd_str;
	
	// build the initial ID string (blank ID)
	char i;
	for(i=0; i<10; i++){
		ID[i] = ' ';
	}
	ID[10]= 0x00; // null terminate
	
	//turn Portb to output
	DDRB = 0xFF;
	//turn off transmitter
	PORTB = (1<<PB0);
	// turn INT0 and INT1 pullup on (PD2) (PD3)
	PORTD = PORTD | (1<<PD2) | (1<<PD3);
	
	// setup timer1 to interrupt every 500ms
	OCR1AH = 0x1E; //7813
	OCR1AL = 0x85;
	//start timer at 0
	TCNT1H = 0;
	TCNT1L = 0;
	// initialize tccr1b: CTC mode, clk/1024
	TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10);
	//set Timer counter 1 Output Compare for interrupt
	TIMSK = (1<<OCIE1A);
	
	//turn on INT0 interrupt
	GICR = (1<<INT0) | (1<<INT1);
	//sets to falling edge trigger for INT0 and INT1
	MCUCR = (MCUCR & 0xF0) | (1<<ISC01) | (1<<ISC11);
	
	//initialize needed peripherals
	usart_init();              // initialize the USART
	lcd_init();                // initialize the LCD
	// not doing initializing
	//lcd_init_heartbeat_icon(); // build the heartbeat icon
	//lcd_init_antenna_icons();  // build the antenna icons
	display_welcome();         // display welcome screen for 
							   // 3 seconds at startup
	
	delay_ms(2);
	// keep system at 2400 Baud until an LCD update needs to be made
	usart_baud(RFID_BAUD_H, RFID_BAUD_L);
	delay_ms(2);
	
	//Enable global interrupts
	sei();
	
	
	//forever loop to update and track program
    while(true){
		//if it is time to update the LCD, we must first disable interrupts
		//and switch the baud to 9600. Then send the data to the screen,
		//switch the baud back to 2400, and re-enable interrupts
		if(update_LCD){
			update_LCD = false;
			//clear global interrupts
			cli();
			delay_ms(2);
			//set baud rate for LCD
			usart_baud(LCD_BAUD_H, LCD_BAUD_L);
			delay_ms(2);
			//if the welcome message is not displayed 
			//than display the ID on the second line
			// after the 3 second welcome screen, display any IDs found
			if(!welcome){
				lcd_gotoxy(0,0);
				printf("CE3200 RFID    ");
				lcd_gotoxy(1,0);
				//display the number of tags seen if the button was pressed
				//this will be displayed until another tag is read
				if(display_tag_count){
					printf("COUNT= %u     ",tag_count); // writes 5 spaces to clear anything that was previously there
					if(tag_count < 10)
						printf("  "); // write 2 more spaces if the number only has 1 digit
					else if(tag_count < 100)
						printf(" "); // write 1 more space if the number has 2 digits
				}
				//else display the ID of the Tag
				else{
					printf("ID= %s ",ID);
				}		
				lcd_gotoxy(1,15);	
				//send the antenna signal
				if(antenna){
					lcd_send_data('*');
				}
				else{
					lcd_send_data('_');
				}
				
			}
			
			//check to see if the Heart Beat Icon should be displayed
			if(heartBeat){
				lcd_gotoxy(0,15);
				//send custom character for the heart
				//lcd_send_data(0); 
				lcd_send_data('H');
			}
			else{
				lcd_gotoxy(0,15);
				lcd_send_data(' ');
			}
			delay_ms(2);
			//set baud rate for the RFID
			usart_baud(RFID_BAUD_H, RFID_BAUD_L);
			delay_ms(2);
			//enable global interrupts
			sei();
		}		
    }
}

/*
 * INT0_vect
 * Purpose: This sets a flag to toggle the RFID antenna
 */
ISR(INT0_vect){
	toggle_RFID();
}

/*
 * INT1_vect
 * Purpose: This will set a flag to display the Tag's seen count
 */
ISR(INT1_vect){
	display_tag_count = true;
}

/*
 * USART_RXC_vect
 * Purpose: To read in from the RFID the number and store it to be
 *			displayed on the LCD
 */
ISR(USART_RXC_vect){
	char c = UDR;
	// indicates start of new ID
	if(c == '\n'){
		byte_count = 0;
	}	
	// indicates end of new ID
	else if(c == '\r'){
		ID[10] = 0x00;
		//increment the number of tags seen
		tag_count++;
		//turn off the display of the number of tags
		display_tag_count = false;
	}	
	// the char received was part of the ID
	else{
		ID[byte_count] = c;
		byte_count++;
	}	
}

/* 
 * TIMER1_COMPA_vect
 * Purpose: This will handle the heartbeat being displayed
 *			on the lcd every half a second.
 */
ISR(TIMER1_COMPA_vect){
	//check to see if the welcome message is done displaying
	if((welcome_count++) > 6)
		welcome = false;
	
	// toggle the heartbeat
	heartBeat = !(heartBeat);
	//set variable to update the lcd
	update_LCD = true;
}